#include<unistd.h>
#include<netdb.h>
#include<sys/socket.h>
#include<errno.h>
#include<signal.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>

#define BUFLEN 128
#define TIMEOUT 20

void sigalrm(int signo)
{
}

void print_uptime(int sockfd, struct addrinfo *aip)
{
	int n;
	char buf[BUFLEN];

	buf[0] = 0;
	if(sendto(sockfd, buf, 1, 0, aip->ai_addr, aip->ai_addrlen) < 0)
		err_sys("sendto error");
	alarm(TIMEOUT);
	if((n = recvfrom(sockfd, buf, BUFLEN, 0, NULL, NULL)) < 0) {
		if(errno != EINTR)
			alarm(0);
		err_sys("recvfrom error");
	}
	alarm(0);
	write(STDOUT_FILENO, buf, n);
}

int main(int argc, char *argv[])
{
	struct addrinfo *ailist, *aip;
	struct addrinfo hint;
	int sockfd, err;
	struct sigaction sa;

	if(argc != 2)
		err_quit("usage: ruptime hostname");
	sa.sa_handler = sigalrm;
	sa.sa_flags = 0;
	sigemptyset(&sa.sa_mask);
	sigaction(SIGALRM, &sa, NULL);

	hint.ai_flags = 0;
	hint.ai_family = 0;
	hint.ai_socktype = SOCK_DGRAM;
	hint.ai_protocol = 0;
	hint.ai_addrlen = 0;
	hint.ai_canonname = NULL;
	hint.ai_addr = NULL;
	hint.ai_next = NULL;

	if((err = getaddrinfo(argv[1], "ruptime", &hint, &ailist)) != 0)
		err_quit("getaddrinfo error: %s", gai_strerror(err));

	for(aip=ailist; aip!=NULL; aip=aip->ai_next) {
		if((sockfd = socket(aip->ai_family, SOCK_DGRAM, 0)) < 0)
			err = errno;
		else {
			print_uptime(sockfd, aip);
			exit(0);
		}
	}
	fprintf(stderr, "Can't contact %s: %s\n", argv[1], strerror(err));
	exit(1);
}
